# -*-coding:utf-8-*-
import re
from django.conf import settings
from rest_framework_jwt.serializers import serializers
from itsdangerous import TimedJSONWebSignatureSerializer as TJS
from rest_framework_jwt.settings import api_settings

from oauth.models import OAuthUser
from users.models import User
from verifications.views import SMSCodeView, ImageCheckViews


class QQOauthSerializers(serializers.ModelSerializer):
    """QQ用户绑定的序列化起"""
    # 指名模型类中没有的字段
    mobile = serializers.CharField(max_length=11)
    sms_code = serializers.CharField(max_length=6, min_length=6, write_only=True)
    access_token = serializers.CharField(write_only=True)   # 反序列化输入

    token = serializers.CharField(read_only=True)
    user_id = serializers.IntegerField(read_only=True)  # 序列化输出


    class Meta:
        model=User
        fields=('password', 'mobile', 'username', 'sms_code', 'token','access_token', 'user_id')

        extra_kwargs = {
            'username':{
                'read_only':True
            },
            'password':{
                'write_only':True
            }
        }

    def validated_mobile(self, value):
        """
        验证手机号
        :param value:
        :return:
        """
        if not re.match(r"1[3-9]\d{9}$", value):
            raise serializers.ValidationError("手机号格式错误")
        return value


    def validate(self, attrs):
        """
        验证access_token
        :param attrs:
        :return:
        """
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(attrs["access_token"]) # 解析token
        except:
            raise serializers.ValidationError("无效的token")

        # 获取openid
        openid = data.get("openid")
        # attrs中添加openid
        attrs["openid"] = openid
        # 验证短信验证码:
        rel_sms_code = SMSCodeView.checkSMSCode(attrs["mobile"])
        if not rel_sms_code:
            raise serializers.ValidationError('短信验证码失效')
            # 3、比对用户输入的短信和redis中真实短信
        if attrs['sms_code'] != rel_sms_code:
            raise serializers.ValidationError('短信验证不一致')

        # 验证手机号是否被注册过
        try:
            user = User.objects.get(mobile=attrs['mobile'])
        except:
            # 未注册过，注册为新用户
            return attrs
        else:
            # 注册过 查询用户进行绑定
            # 判断密码
            if not user.check_password(attrs['password']):
                raise serializers.ValidationError('密码错误')
            attrs['user'] = user
            return attrs

    def create(self, validated_data):
        """
        保存用户
        :param self:
        :param validated_data:
        :return:
        """
        # 判断用户
        user = validated_data.get('user', None)
        if user is None:
            # 创建用户
            user = User.objects.create_user(username=validated_data['mobile'],
                                            password=validated_data['password'],
                                            mobile=validated_data['mobile'])
        # 绑定操作
        OAuthUser.objects.create(user=user, openid=validated_data["openid"])
        # user_id=user.id
        # 生成加密后的token数据
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)  # 生成载荷部分
        token = jwt_encode_handler(payload)  # 生成token

        # user添加token属性
        user.token = token
        user.user_id = user.id

        return user

class WeiboOauthSerializers(serializers.ModelSerializer):
    """微博验证序列化器"""

    # 指名模型类中没有的字段
    mobile = serializers.CharField(max_length=11)
    sms_code = serializers.CharField(max_length=6, min_length=6, write_only=True)
    access_token = serializers.CharField(write_only=True)  # 反序列化输入

    token = serializers.CharField(read_only=True)
    user_id = serializers.IntegerField(read_only=True)  # 序列化输出

    class Meta:
        model = User
        fields = ('password', 'mobile', 'username', 'sms_code', 'token', 'access_token', 'user_id')

        extra_kwargs = {
            'username': {
                'read_only': True
            },
            'password': {
                'write_only': True
            }
        }

    def validated_mobile(self, value):
        """
        验证手机号
        :param value:
        :return:
        """
        if not re.match(r"1[3-9]\d{9}$", value):
            raise serializers.ValidationError("手机号格式错误")
        return value

    def validate(self, attrs):
        """
        验证access_token
        :param attrs:
        :return:
        """
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(attrs["access_token"])  # 解析token
        except:
            raise serializers.ValidationError("无效的token")

        # 获取weibotoken
        weibotoken = data.get("weibotoken")
        # attrs中添加weibotoken
        attrs["weibotoken"] = weibotoken
        # 验证短信验证码:
        rel_sms_code = SMSCodeView.checkSMSCode(attrs["mobile"])
        if not rel_sms_code:
            raise serializers.ValidationError('短信验证码失效')
            # 3、比对用户输入的短信和redis中真实短信
        if attrs['sms_code'] != rel_sms_code:
            raise serializers.ValidationError('短信验证不一致')
        # 验证手机号是否被注册过
        try:
            user = User.objects.get(mobile=attrs['mobile'])
        except:
            # 未注册过，注册为新用户
            return attrs
        else:
            # 注册过 查询用户进行绑定
            # 判断密码
            if not user.check_password(attrs['password']):
                raise serializers.ValidationError('密码错误')
            attrs['user'] = user
            return attrs

    def create(self, validated_data):
        """
        保存用户
        :param self:
        :param validated_data:
        :return:
        """
        # 判断用户
        user = validated_data.get('user', None)
        if user is None:
            # 创建用户
            user = User.objects.create_user(username=validated_data['mobile'],
                                            password=validated_data['password'],
                                            mobile=validated_data['mobile'])
        # 绑定操作
        OAuthUser.objects.create(user=user, weibotoken=validated_data["weibotoken"])
        # user_id=user.id
        # 生成加密后的token数据
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)  # 生成载荷部分
        token = jwt_encode_handler(payload)  # 生成token

        # user添加token属性
        user.token = token
        user.user_id = user.id

        return user




